Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert MATH plugin data into more usable form in UFO #980

Merged
merged 6 commits into from
Feb 17, 2024
Merged

Conversation

khaledhosny
Copy link
Collaborator

@khaledhosny khaledhosny commented Feb 12, 2024

The Glyphs MATH plugin stores its data in master, glyph, and layer userData. Master and layer userData convert seamlessly to UFO font and layer lib. Glyph userData, however, have no equivalent in UFO so we store them in the font’s lib under a per-glyph key prefixed by glyphsLib prefix, but this is a bit ugly. So this change groups them under two common keys using the same prefix as the other keys.

So instead of:

<key>com.schriftgestaltung.Glyphs.glyphUserData.braceright</key>
<dict>
        <key>com.nagwa.MATHPlugin.extendedShape</key>
        <integer>1</integer>
        <key>com.nagwa.MATHPlugin.variants</key>
        <dict>
                <key>vVariants</key>
                <array>
                ...
                </array>
        </dict>
</dict>
<key>com.schriftgestaltung.Glyphs.glyphUserData.braceleft</key>
<dict>
        <key>com.nagwa.MATHPlugin.extendedShape</key>
        <integer>1</integer>
        <key>com.nagwa.MATHPlugin.variants</key>
        <dict>
                <key>vVariants</key>
                <array>
                ...
                </array>
        </dict>
</dict>

We now save:

<key>com.nagwa.MATHPlugin.extendedShape</key>
<array>
        <string>parenleft</string>
        <string>parenright</string>
        ....
</array>
<key>com.nagwa.MATHPlugin.variants</key>
<dict>
        <key>parenleft</key>
        <dict>
             <key>vVariants</key>
             <array>
             ...
             <array>
        </dict>
        <key>parenleft</key>
        <dict>
             <key>vVariants</key>
             <array>
             ...
             <array>
        </dict>
        ...
</dict>

Copy link
Member

@anthrotype anthrotype left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense to group per-glyph userdata under same font lib key. I wonder if we could make this more general instead of ad-hoc for the MATH plugin. I imagine we might want to give similar treatment to other stuff that may live in userDatas

@khaledhosny
Copy link
Collaborator Author

makes sense to group per-glyph userdata under same font lib key. I wonder if we could make this more general instead of ad-hoc for the MATH plugin. I imagine we might want to give similar treatment to other stuff that may live in userDatas

Makes sense. It might not allow for efficient representation of boolean data, e.g. isExtendedShape is saved as a simple list of glyph names because I know it is a boolean, but in general I don’t think Glyphs file format distinguishes between boolean and integers, so if this is done generically it will be a dictionary.

@khaledhosny
Copy link
Collaborator Author

makes sense to group per-glyph userdata under same font lib key. I wonder if we could make this more general instead of ad-hoc for the MATH plugin. I imagine we might want to give similar treatment to other stuff that may live in userDatas

Makes sense. It might not allow for efficient representation of boolean data, e.g. isExtendedShape is saved as a simple list of glyph names because I know it is a boolean, but in general I don’t think Glyphs file format distinguishes between boolean and integers, so if this is done generically it will be a dictionary.

Thinking more about it, I think also handling this generically will be hard to round-trip. Right now I know that certain font lib keys are actually glyph-level userData, but I have no way of knowing this in the generic case.

My use case here is to get the data to ufo2ft (googlefonts/ufo2ft#819) and I’m trying to avoid making ufo2ft side too GlyphsApp-specific, hence trying to make the data here usable for a UFO-only workflow as well.

@khaledhosny khaledhosny marked this pull request as ready for review February 14, 2024 01:48
for key, value in ufo.lib.items():
if _user_data_has_no_special_meaning(key):
if _user_data_has_no_special_meaning(key) and key not in special_math_keys:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe you should add the math keys to _user_data_has_no_special_meaning?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_user_data_has_no_special_meaning is used in multiple places and in some of them we want to skip MATH key and in others we don’t.

@khaledhosny khaledhosny marked this pull request as draft February 16, 2024 07:20
The Glyphs MATH plugin stores its data in master, glyph, and layer
userData.  Master and layer userData convert seamlessly to UFO font and
layer lib. Glyph userData, however, have no equivalent in UFO so we
store them in the font’s lib under a per-glyph key prefixed by glyphsLib
prefix, but this is a bit ugly. So this change groups them under two
common keys using the same prefix as the other keys.

So instead of:

    <key>com.schriftgestaltung.Glyphs.glyphUserData.braceright</key>
    <dict>
            <key>com.nagwa.MATHPlugin.extendedShape</key>
            <integer>1</integer>
            <key>com.nagwa.MATHPlugin.variants</key>
            <dict>
                    <key>vVariants</key>
                    <array>
                    ...
                    </array>
            </dict>
    </dict>
    <key>com.schriftgestaltung.Glyphs.glyphUserData.braceleft</key>
    <dict>
            <key>com.nagwa.MATHPlugin.extendedShape</key>
            <integer>1</integer>
            <key>com.nagwa.MATHPlugin.variants</key>
            <dict>
                    <key>vVariants</key>
                    <array>
                    ...
                    </array>
            </dict>
    </dict>

We now save:

    <key>com.nagwa.MATHPlugin.extendedShape</key>
    <array>
            <string>parenleft</string>
            <string>parenright</string>
            ....
    </array>
    <key>com.nagwa.MATHPlugin.variants</key>
    <dict>
            <key>parenleft</key>
            <dict>
                 <key>vVariants</key>
                 <array>
                 ...
                 <array>
            </dict>
            <key>parenleft</key>
            <dict>
                 <key>vVariants</key>
                 <array>
                 ...
                 <array>
            </dict>
            ...
    </dict>
We write it to the glyph userData where they belong.
The Glyphs MATH plugin makes distinction between userData that does not
change per master and stores them in glyph.userDara, and that changes
per-master and stores then in layer.userData. When writing to UFO we
were maintaining this distinction by keeping the former in font.lib and
the layer in glyph.lib.

But since a UFO file represent a single master, this distinction makes
no much sense, and the UFO data looks split arbitrarily. We now keep
both glyph and layer userData in glyph.lib. When converting from UFO to
Glyphs if the glyph-level data is different between UFO masters, we
issue a warning.
@khaledhosny khaledhosny marked this pull request as ready for review February 17, 2024 02:44
@khaledhosny khaledhosny merged commit 1f863f6 into main Feb 17, 2024
10 checks passed
@khaledhosny khaledhosny deleted the math-table branch February 17, 2024 14:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants